/**
 * meiguang8.com
 * Copyright (C) 2016-2019 All Rights Reserved.
 */
package com.yuanchuang.yp.mall.web.admin.common.utils;

import com.yuanchuang.yp.mall.web.admin.common.config.spring.SpringHelper;
import org.apache.commons.lang3.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * @author zdb
 * @version AesEncodeUtil.java, v 0.1 2019-04-19 16:33
 */
public class AesEncodeUtil {

    //初始向量
    private static byte[] AESIV = {0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F};
    public static final String VIPARA = "aabbccddeeffgghh";   //AES 为16bytes. DES 为8bytes

    //编码方式
    public static final String bm = "UTF-8";

    //私钥
    private static final String ASE_KEY = SpringHelper.getStaticAesEncodeKey();   //AES固定格式为128/192/256 bits.即：16/24/32bytes。DES固定格式为128bits，即8bytes。

    /**
     * 加密
     *
     * @param cleartext
     * @return
     */
    public static String encrypt(String cleartext) {
        //加密方式： AES128(CBC/PKCS5Padding) + Base64, 私钥：aabbccddeeffgghh
        try {
            IvParameterSpec zeroIv = new IvParameterSpec(AESIV);
            //两个参数，第一个为私钥字节数组， 第二个为加密方式 AES或者DES
            SecretKeySpec key = new SecretKeySpec(ASE_KEY.getBytes(), "AES");
            //实例化加密类，参数为加密方式，要写全
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //PKCS5Padding比PKCS7Padding效率高，PKCS7Padding可支持IOS加解密
            //初始化，此方法可以采用三种方式，按加密算法要求来添加。（1）无第三个参数（2）第三个参数为SecureRandom random = new SecureRandom();中random对象，随机数。(AES不可采用这种方法)（3）采用此代码中的IVParameterSpec
            cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
            //加密操作,返回加密后的字节数组，然后需要编码。主要编解码方式有Base64, HEX, UUE,7bit等等。此处看服务器需要什么编码方式
            byte[] encryptedData = cipher.doFinal(cleartext.getBytes(bm));

            return new BASE64Encoder().encode(encryptedData);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解密
     *
     * @param encrypted
     * @return
     */
    public static String decrypt(String encrypted) {
        try {
            byte[] byteMi = new BASE64Decoder().decodeBuffer(encrypted);
            IvParameterSpec zeroIv = new IvParameterSpec(AESIV);
            SecretKeySpec key = new SecretKeySpec(
                    ASE_KEY.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            //与加密时不同MODE:Cipher.DECRYPT_MODE
            cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
            byte[] decryptedData = cipher.doFinal(byteMi);
            return new String(decryptedData, bm);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 解密
     *
     * @param request
     * @return
     */
    public static String decrypt(HttpServletRequest request) {
        String value = request.getHeader("Authorization");
        System.out.println(value);
        if(StringUtils.isNotBlank(value)){
            try {
                value = URLDecoder.decode(value, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return "";
            }
            String userInfo = AesEncodeUtil.decrypt(value);
            System.out.println(userInfo);
            return userInfo;
        }
        return "";
    }

    /**
     * 测试
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {


//        String content = "b5X8dIOVgXnYtOEMX4HGLw==";
//        // 加密
//        System.out.println("加密前：" + content);
//        String encryptResult = encrypt(content);
//
//        System.out.println("加密后：" + new String(encryptResult));
        // 解密
        String vlue = "w0wTVuNAKfPugQZUD8sj9ZgRj40Zwt56QlIWUnKOUDU%3d";
        String decode = URLDecoder.decode(vlue, "utf-8");
        String decryptResult = decrypt(decode);
        System.out.println("解密后：" + new String(decryptResult));


    }


}
